package com.logistics.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.logistics.entity.SysPermission;
import com.logistics.entity.SysRole;
import com.logistics.entity.SysRolePermission;
import com.logistics.mapper.SysPermissionMapper;
import com.logistics.mapper.SysRoleMapper;
import com.logistics.mapper.SysRolePermissionMapper;
import com.logistics.common.TenantContextHolder;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

/**
 * 角色服务类
 */
@Service
public class RoleService {
    
    @Autowired
    private SysRoleMapper roleMapper;
    
    @Autowired
    private SysRolePermissionMapper rolePermissionMapper;
    
    @Autowired
    private SysPermissionMapper permissionMapper;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    /**
     * 分页查询角色列表
     */
    public IPage<SysRole> getRoleList(int current, int size, String keyword) {
        Long tenantId = TenantContextHolder.getTenantId();
        
        Page<SysRole> page = new Page<>(current, size);
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getTenantId, tenantId);
        
        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w.like(SysRole::getRoleName, keyword)
                            .or()
                            .like(SysRole::getRoleCode, keyword));
        }
        
        wrapper.orderByDesc(SysRole::getCreateTime);
        
        return roleMapper.selectPage(page, wrapper);
    }
    
    /**
     * 获取角色的权限列表（返回权限代码）
     */
    public List<String> getRolePermissions(Long roleId) {
        SysRole role = roleMapper.selectById(roleId);
        if (role == null || role.getPermissions() == null || role.getPermissions().isEmpty()) {
            return new ArrayList<>();
        }
        
        try {
            return objectMapper.readValue(role.getPermissions(), new TypeReference<List<String>>() {});
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
    
    /**
     * 创建角色
     */
    public SysRole createRole(SysRole role) {
        Long tenantId = TenantContextHolder.getTenantId();
        
        // 如果没有提供角色代码，自动生成
        if (role.getRoleCode() == null || role.getRoleCode().isEmpty()) {
            role.setRoleCode(generateRoleCode(tenantId));
        } else {
            // 检查角色代码是否重复
            LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysRole::getTenantId, tenantId)
                   .eq(SysRole::getRoleCode, role.getRoleCode());
            
            if (roleMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("角色代码已存在");
            }
        }
        
        role.setTenantId(tenantId);
        role.setIsSystem(0);  // 自定义角色
        roleMapper.insert(role);
        
        return role;
    }
    
    /**
     * 生成唯一的角色代码
     */
    private String generateRoleCode(Long tenantId) {
        String prefix = "ROLE_";
        int suffix = 1;
        String roleCode;
        
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getTenantId, tenantId);
        
        // 查找已有的最大编号
        List<SysRole> roles = roleMapper.selectList(wrapper);
        for (SysRole r : roles) {
            if (r.getRoleCode() != null && r.getRoleCode().startsWith(prefix)) {
                try {
                    String numStr = r.getRoleCode().substring(prefix.length());
                    int num = Integer.parseInt(numStr);
                    if (num >= suffix) {
                        suffix = num + 1;
                    }
                } catch (NumberFormatException ignored) {
                }
            }
        }
        
        // 生成新的角色代码并确保唯一
        do {
            roleCode = prefix + suffix;
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysRole::getTenantId, tenantId)
                   .eq(SysRole::getRoleCode, roleCode);
            if (roleMapper.selectCount(wrapper) == 0) {
                break;
            }
            suffix++;
        } while (true);
        
        return roleCode;
    }
    
    /**
     * 更新角色
     */
    public void updateRole(SysRole role) {
        // 检查是否是系统角色
        SysRole existingRole = roleMapper.selectById(role.getId());
        if (existingRole.getIsSystem() == 1) {
            throw new RuntimeException("管理员角色不可修改");
        }
        
        // 不允许修改为保留的内置角色代码
        if (role.getRoleCode() != null) {
            String code = role.getRoleCode();
            if ("PLATFORM_ADMIN".equals(code) || "SUPER_ADMIN".equals(code) || "SITE_ADMIN".equals(code)) {
                throw new RuntimeException("不允许使用保留的角色代码");
            }
        }
        
        roleMapper.updateById(role);
    }
    
    /**
     * 删除角色
     */
    @Transactional
    public void deleteRole(Long id) {
        // 检查是否是系统角色
        SysRole role = roleMapper.selectById(id);
        if (role.getIsSystem() == 1) {
            throw new RuntimeException("管理员角色不可删除");
        }
        
        // 删除角色
        roleMapper.deleteById(id);
    }
    
    /**
     * 为角色分配权限（保存权限代码）
     */
    @Transactional
    public void assignPermissions(Long roleId, List<String> permissionCodes) {
        SysRole role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        // 只有SUPER_ADMIN角色拥有所有权限，不允许修改
        // SITE_ADMIN等其他系统角色的权限可以由更高级别的管理员配置
        if (role.getIsSystem() == 1 && "SUPER_ADMIN".equals(role.getRoleCode())) {
            throw new RuntimeException("超级管理员拥有所有权限，无需配置");
        }
        
        try {
            // 将权限代码列表转换为 JSON 字符串
            String permissionsJson = objectMapper.writeValueAsString(permissionCodes);
            role.setPermissions(permissionsJson);
            roleMapper.updateById(role);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("保存权限失败");
        }
    }
}

